#pragma once

#include"Logger.h"
#include<iostream>
#include<fstream>
#include<time.h>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<Windows.h>

using namespace std;

namespace loggingService{

	Logger* Logger::instance = NULL;

	string Logger::LOGFILENAME = "logg.txt";

	Logger* Logger::getLogger(){

		if(Logger::instance == NULL)
		{
			Logger::instance = new Logger();	
			Logger::instance->logfile_open();
		}
		return Logger::instance;

	};


	void Logger::log_beginofline(LoggLevel pLogglevel){

		struct tm *localTime;
		time_t mytime;

		time(&mytime);
		localTime = localtime(&mytime);

		Logger::logfile << localTime->tm_mday << "." << localTime->tm_mon + 1 << "." << localTime->tm_year +1900 <<" " 
			<< localTime->tm_hour << ":" << localTime->tm_min << ":" << localTime->tm_sec << " ";

		cout << localTime->tm_mday << "." << localTime->tm_mon + 1 << "." << localTime->tm_year +1900 <<" " 
			<< localTime->tm_hour << ":" << localTime->tm_min << ":" << localTime->tm_sec << " ";

		switch(pLogglevel)
		{
			case debug:
				Logger::logfile << "[debug] ";
				cout << "[debug] ";
				break;
			case info:
				Logger::logfile << "[info] ";
				cout << "[info] ";
				break;
			case warning:
				Logger::logfile << "[warning] ";
				cout << "[warning] ";
				break;
			case error:
				Logger::logfile << "[error] ";
				cout << "[error] ";
				break;
			default:
				Logger::logfile << "[unknown] ";
				cout << "[unknown] ";
				break;
		};

	};

	HANDLE mutex = CreateMutex( NULL, FALSE, NULL );

	void Logger::log(LoggLevel pLoglevel,string pMessage){
		if ( WaitForSingleObject( mutex, INFINITE ) == WAIT_OBJECT_0 )
        {	
			if(logfile.is_open()){
				Logger::log_beginofline(pLoglevel);
				Logger::logfile << pMessage << endl;
				cout << pMessage << endl;
				Logger::logfile.flush();				
			}
			ReleaseMutex( mutex ); 
		}
	};

	void Logger::logfile_open(){
		if ( WaitForSingleObject( mutex, INFINITE ) == WAIT_OBJECT_0 )
		{ 
			if(!logfile.is_open()){
				Logger::logfile.open(LOGFILENAME);

				if(!Logger::logfile)
				{
					throw -1;
				}
				Logger::instance->log(info,"Logger: Logger started...");
			}
			ReleaseMutex( mutex ); 
		}
	}

	void Logger::logfile_close(){
		if ( WaitForSingleObject( mutex, INFINITE ) == WAIT_OBJECT_0 )
        {	
			if(logfile.is_open()){
				Logger::instance->log(info,"Logger: going down now...");
				Logger::logfile.close();				
			}
			ReleaseMutex( mutex ); 
		}

	}

	Logger::Logger()
	{
	
	};

	Logger::~Logger()
	{	
		Logger::instance->logfile_close();
	}

	void Logger::setlogdir(string pLogdir){
		
		Logger::LOGFILENAME = pLogdir + "\\logg.txt";
	
	}
};